from pyglet.gl import *
import random
import data
import os
from gmobjs import *
from particles import *
from medals import *
import ui

class PatternGenerator:
    def __init__(self, mapobj):
        self.patterns= []
        files = os.listdir(data.data_dir)
        for file in files:
            if file.endswith('.txt'):
                fp = open(data.filepath(file))
                npicks = int(fp.readline())
                plist = []
                for i in xrange(npicks):
                    plist.append(map(int,fp.readline().split(' ')))
                nenemy = int(fp.readline())
                elist = []
                for i in xrange(nenemy):
                    elist.append(map(int,fp.readline().split(' ')))
                fp.close()
                self.patterns.append((plist, elist))

        self.pattern = ([(0,0)],[]) #keeps track of current pattern 
        self.index = -1
        self.particleslist = []
        self.mapobj = mapobj
        self.has_added = False
        self.wave = 0

    def update(self, dt):
        self.index += 1
        if self.index < len(self.pattern[0]):
            picks = self.pattern[0]
            self.particleslist.append(Particle(picks[self.index],(0,0), data.pickup_image.id, -1))

        else:
            idx = self.index - len(self.pattern[0])
            if idx < len(self.pattern[1]):
                elist = self.pattern[1]
                if self.wave > 4:
                    list = [data.e2_image.id, data.e3_image.id]
                else:
                    list = [data.e2_image.id]
                self.particleslist.append(Particle(elist[idx], (0,0), random.choice(list), -1))
        for p in self.particleslist:
            p.update(dt)
            if p.size == Particle.MinSize:
                if p.texid == data.pickup_image.id:
                    self.mapobj.addPickup(p.pos)
                    self.has_added = True 
                elif p.texid == data.e2_image.id:
                    self.mapobj.addInEnemy(p.pos)
                elif p.texid == data.e3_image.id:
                    self.mapobj.addMoveEnemy(p.pos)
                self.particleslist.remove(p)

    def render(self):
        for p in self.particleslist:
            p.render()
        glColor4f(1, 1, 1, 1)

    def getNumPickups(self):
        return len(self.pattern[0])

    def pickPattern(self):
        self.wave += 1
        self.pattern = random.choice(self.patterns)
        self.mapobj.addPowerUp()
        #self.pattern = ([(0,0)],[(50,0)])
        self.has_added = False
        self.index = -1
        #randomly add this
        if self.wave > 2:
            self.mapobj.addOutEnemy()
            self.mapobj.addOutEnemy()
            if self.wave & 1:
                self.mapobj.vel = (-2, 2)
            else:
                self.mapobj.vel = (0, 0)


class ScoreCounter:
    MaxCombo = 10
    def __init__(self):
        self.score = 0
        self.combo = 0
        self.counter = 0
        self.score_label = pyglet.text.HTMLLabel("<font size=4 color=#000000><b>SCORE: %3d </b></font>" % self.score, x=10, y=600-20)
        self.combo_label = pyglet.text.HTMLLabel("<font size=4 color=#000000><b>COMBO: %3d </b></font>" % self.combo, x=10, y=600-40)

    def update(self):
        if self.combo > 0:
            self.counter = self.counter - 1
            if self.counter == 0:
                self.combo = self.combo -1
                self.counter = 50
                self.combo_label.text = "<font size=4 color=#000000><b>COMBO: %3d </b></font>" % self.combo

    def addType(self, type):
#        if type == GameObject.ENEMY or type == GameObject.ENEMY1:
        if type in (GameObject.ENEMY, GameObject.ENEMY1, GameObject.ENEMY2):
            self.addEnemy()
        elif type == GameObject.PICKUP:
            self.addPickup()

    def updateText(self):
        self.combo_label.text = "<font size=4 color=#000000><b>COMBO: %3d </b></font>" % self.combo
        self.score_label.text = "<font size=4 color=#000000><b>SCORE: %3d </b></font>" % self.score
    
    def addEnemy(self):
        self.combo = self.combo + 1
        self.score = self.score - 20 * self.combo
        self.combo = 0
        self.updateText()
        data.crash_sound.play()

    def addPickup(self):
        if self.combo < ScoreCounter.MaxCombo:
            self.combo = self.combo + 1
        self.counter = 50
        self.score = self.score + self.combo
        self.updateText()
        data.pick_sound.play()
    
    def render(self):
        glColor4f(1, 1, 1, 1)
        glBindTexture(GL_TEXTURE_2D, data.rect_image.id)
        glBegin(GL_POLYGON)
        glTexCoord2f(0, 0)
        glVertex2f(0, 600)
        glTexCoord2f(0, 1)
        glVertex2f(0, 600-50)
        glTexCoord2f(1, 1)
        glVertex2f(150, 600-50)
        glTexCoord2f(1, 0)
        glVertex2f(150, 600)
        glEnd()

        self.score_label.draw()
        self.combo_label.draw()

class Map(GameObject):
    def __init__(self):
        GameObject.__init__(self, 200)
        self.pos = (self.bounds[0]/2, self.bounds[1]/2)
        #self.vel = (-2, -2)
        self.vel = (0,0)
        self.type = GameObject.MAP 
        self.hero = Hero(self.r)
        self.hero.pos = (-self.r, 0)
        self.hero.vel = (0, 0)
        self.objs = []
        self.sc = ScoreCounter()
        self.pg = PatternGenerator(self)
        self.medals = Medals()
        self.blasts = []
        self.pop_blasts = []
        glClearColor(1.0, 1.0, 1.0, 1.0)
        glEnable(GL_ALPHA_TEST)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glEnable(GL_TEXTURE_2D)


    def render(self):
        self.sc.render()
        if len(self.medals.popup):
            ui.drawPopUp(self.medals.popup[0])
        glColor3f(1, 1, 1)
        glBindTexture(GL_TEXTURE_2D, data.map_image.id)
        glBegin(GL_POLYGON)
        glTexCoord2f(0, 0)
        glVertex2f(self.pos[0]-self.r, self.pos[1]-self.r)
        glTexCoord2f(0, 0.975)
        glVertex2f(self.pos[0]-self.r, self.pos[1]+self.r)
        glTexCoord2f(1, 0.975)
        glVertex2f(self.pos[0]+self.r, self.pos[1]+self.r)
        glTexCoord2f(1, 0)
        glVertex2f(self.pos[0]+self.r, self.pos[1]-self.r)
        glEnd()

        for b in self.pop_blasts:
            b.render()

        glPushMatrix()
        glTranslatef(self.pos[0], self.pos[1], 0)
        #draw inner objects
        for blast in self.blasts:
            blast.render()
        self.pg.render()
        self.hero.render()
        for obj in self.objs:
            obj.render()
        glPopMatrix()

    def update(self, dt):
        var = 0
        v1 = self.vel   #before update
        GameObject.update(self, dt)
        v2 = self.vel   #after update
        if not(v1 == v2): #bounce occured increment jj
            self.medals.jj += 1

        self.hero.update(dt)
        self.pg.update(dt)
        hp = self.hero.pos
        hr = self.hero.r
        wp = self.pos
        if hp[0]+wp[0]-hr < 0 or hp[0]+wp[0]+hr > self.bounds[0]:
            data.crash_sound.play()
            self.blasts.append(Blast(self.hero.pos, data.getTexture(self.hero.type).id, False))
            if self.medals.jj:
                self.medals.jj = 0
                print "Ouch"   #player got crushed
                self.hero.noPowerUp()   #all powerups lost when getting crushed.
                self.sc.addEnemy()
        elif hp[1]+wp[1]-hr < 0 or hp[1]+wp[1]+hr > self.bounds[1]:
            self.blasts.append(Blast(self.hero.pos, data.getTexture(self.hero.type).id, False))
            data.crash_sound.play()
            if self.medals.jj:
                print "Ouch"    #player got crushed
                self.medals.jj = 0
                self.sc.addEnemy()
                self.hero.noPowerUp()

        for obj in self.objs:
            if self.hero.powerup == GameObject.POWERUP_B:
                if obj.type in (GameObject.ENEMY): #(GameObject.ENEMY1, GameObject.ENEMY) destroy only the static enemies:
                    self.objs.remove(obj)
                    self.blasts.append(Blast(obj.pos, data.getTexture(obj.type).id, False))
                    self.sc.addType(GameObject.PICKUP)
                    continue
            obj.update(dt)
            if hasattr(obj,'timer'):
                if obj.timer < 0:
                    self.objs.remove(obj)
                    self.blasts.append(Blast(obj.pos, data.getTexture(obj.type).id, False))
                    continue
            if obj.type == GameObject.ENEMY1:
                if obj.pos[0]+wp[0]-obj.r < 0 or obj.pos[0]+wp[0]+obj.r > self.bounds[0]:
                    data.crash_sound.play()
                    #enemy got crushed
                    self.objs.remove(obj)
                    self.blasts.append(Blast(obj.pos, data.getTexture(obj.type).id, False))
                    self.medals.ec += 1
                    continue
                elif obj.pos[1]+wp[1]-obj.r < 0 or obj.pos[1]+wp[1]+obj.r > self.bounds[1]:
                    data.crash_sound.play()
                    #enemy got crushed
                    self.blasts.append(Blast(obj.pos, data.getTexture(obj.type).id, False))
                    self.objs.remove(obj)
                    self.medals.ec += 1
                    continue
            if obj.collision(self.hero):
                self.objs.remove(obj)
                self.blasts.append(Blast(obj.pos, data.getTexture(obj.type).id, False))
                if obj.type in (GameObject.POWERUP_I, GameObject.POWERUP_S, GameObject.POWERUP_B):
                    self.hero.setPowerUp(obj)
                    self.medals.npup += 1
                elif obj.type in (GameObject.ENEMY, GameObject.ENEMY1, GameObject.ENEMY2): 
                    if (self.hero.powerup == GameObject.POWERUP_I):
                        self.sc.addType(GameObject.PICKUP)
                    else:
                        self.sc.addType(obj.type)
                        self.hero.noPowerUp() #remove other powerups that the hero might have
                    if obj.type in (GameObject.ENEMY, GameObject.ENEMY2):
                        self.addOutEnemy()
                    self.blasts.append(Blast(self.hero.pos, data.getTexture(self.hero.type).id, False))
                    self.medals.tmn = 0
                elif obj.type == GameObject.PICKUP:
                    self.sc.addType(obj.type)
            if obj.type == GameObject.PICKUP:
                var = var + 1

        if var == 0 and self.pg.has_added:
            self.medals.tmn += 1
            self.pg.pickPattern()

        for blast in self.blasts:
            blast.update(dt)
            if blast.done:
                self.blasts.remove(blast)

        for b in self.pop_blasts:
            b.update(dt)
            if b.done:
                self.pop_blasts.remove(b)

        self.sc.update()
        self.medals.sd = self.sc.score
        self.medals.wave = self.pg.wave
        self.medals.update()
        if len(self.medals.popup):
            ui.updatePopUp()
            if ui.pop_done:
                if ui.time_var < 2:
                    p = ui.pop_show
                    self.pop_blasts.append(Blast(p, data.pickup_image.id, True))
                    self.pop_blasts.append(Blast((p[0]+ui.pop_w,p[1]), data.pickup_image.id, True))
                if ui.time_var == 60:
                    ui.resetPop()
                    self.medals.popup= []
                    self.pop_blasts = []

    def addPickup(self, pos):
        obj = PickUp()
        obj.pos = pos
        self.objs.append(obj)

    def addPowerUp(self):
        angle = random.randint(0, 360)
        pos = (self.r * cos(angle), self.r * sin(angle))
        obj = PowerUp(random.choice([GameObject.POWERUP_S, GameObject.POWERUP_I, GameObject.POWERUP_B]), pos)
        self.objs.append(obj)

    def addOutEnemy(self):
        obj = OutEnemy(self.r)
        self.objs.append(obj)
    
    def addMoveEnemy(self, pos):
        obj = MoveEnemy(self.r, self.hero)
        obj.pos = pos
        self.objs.append(obj)

    def addInEnemy(self, pos):
        obj = InEnemy()
        obj.pos = pos #(r*cos(angle), r*sin(angle))
        self.objs.append(obj)

    def setHeroVel(self, vel):
            self.hero.setVel(vel)
#        if self.hero.vel == (0, 0):
#            #self.hero.vel = (-self.vel[0] + vel[0]*5, -self.vel[1] + vel[1]*5)
#            if self.sc.combo > 7: 
#                factor = 7
#            else:
#                factor = 5
#            self.hero.vel = (vel[0]*factor, vel[1]*factor)

    def drawGuide(self, p1, p2):
        if self.hero.vel == (0, 0):
            glDisable(GL_TEXTURE_2D)
            glColor3f(0, 0, 0)
            glBegin(GL_LINES)
            glVertex2f(p1[0], p1[1])
            glVertex2f(p2[0], p2[1])
            glEnd()
            glEnable(GL_TEXTURE_2D)

